/*
 * The contents of this web application are subject to the Mozilla Public License Version 
 * 1.1 (the "License"); you may not use this web application except in compliance with 
 * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
 * for the specific language governing rights and limitations under the License.
 * 
 * The Original Code is owned by and the Initial Developer of the Original Code is 
 * Composite A/S (Danish business reg.no. 21744409). All Rights Reserved
 * 
 * Section 11 of the License is EXPRESSLY amended to include a provision stating 
 * that any dispute, including but not limited to disputes related to the enforcement 
 * of the License, to which Composite A/S as owner of the Original Code, as Initial 
 * Developer or in any other role, becomes a part to shall be governed by Danish law 
 * and be initiated before the Copenhagen City Court ("K�benhavns Byret")            
 */

using System;
using System.Collections.Generic;
using System.Linq;
using Composite.C1Console.Elements;
using Composite.C1Console.Security;
using Composite.C1Console.Trees.Foundation;
using Composite.Core.ResourceSystem;


namespace Composite.C1Console.Trees
{    
    internal class SimpleElementTreeNode : TreeNode
    {
        public string Label { get; internal set; }              // Requried
        public string ToolTip { get; internal set; }            // Defaults to Label
        public ResourceHandle Icon { get; internal set; }       // Defaults to 'folder'
        public ResourceHandle OpenIcon { get; internal set; }   // Defaults to 'open-folder' or if Icon is set, then, Icon

        // Cached values
        internal DynamicValuesHelper LabelDynamicValuesHelper { get; set; }
        internal DynamicValuesHelper ToolTipDynamicValuesHelper { get; set; }


        public override IEnumerable<EntityToken> GetEntityTokens(EntityToken childEntityToken, TreeNodeDynamicContext dynamicContext)
        {
            EntityToken possibleCurrentEntityToken;

            TreeSimpleElementEntityToken treeSimpleElementEntityToken = childEntityToken as TreeSimpleElementEntityToken;
            if (treeSimpleElementEntityToken != null) {
                possibleCurrentEntityToken = treeSimpleElementEntityToken.ParentEntityToken;
            }
            else
            {
                possibleCurrentEntityToken = childEntityToken;
            }

            foreach (EntityToken entityToken in this.ParentNode.GetEntityTokens(possibleCurrentEntityToken, dynamicContext))
            {
                yield return new TreeSimpleElementEntityToken(this.Id, this.Tree.TreeId, EntityTokenSerializer.Serialize(entityToken));
            }
        }


        internal override IEnumerable<EntityToken> FilterParentGeneretedEntityTokens(EntityToken selfEntityToken, IEnumerable<EntityToken> parentGeneretedEntityTokens, TreeNodeDynamicContext dynamicContext)
        {
            // Check below ensures that the parent EntityToken actually present in a tree and not been filtered out

            TreeSimpleElementEntityToken treeSimpleElementEntityToken = (TreeSimpleElementEntityToken) selfEntityToken;
            EntityToken parentEntityToken = treeSimpleElementEntityToken.ParentEntityToken;
            foreach (EntityToken entityToken in parentGeneretedEntityTokens)
            {
                if (parentEntityToken.Equals(entityToken))
                {
                    return new[] { parentEntityToken };
                }

                TreeSimpleElementEntityToken castedEntityToken = entityToken as TreeSimpleElementEntityToken;
                if ((castedEntityToken != null) &&
                    (parentEntityToken.Equals(castedEntityToken.ParentEntityToken)))
                {
                    return new [] { parentEntityToken };
                }
            }

            return new EntityToken[0];
        }


        public override AncestorResult GetParentEntityToken(EntityToken ownEntityToken, Type parentInterfaceOfInterest, TreeNodeDynamicContext dynamicContext)
        {            
            return new AncestorResult(this.ParentNode, ((TreeSimpleElementEntityToken)ownEntityToken).ParentEntityToken);
        }



        protected override IEnumerable<Element> OnGetElements(EntityToken parentEntityToken, TreeNodeDynamicContext dynamicContext)
        {
            var entityToken = new TreeSimpleElementEntityToken(
                this.Id, 
                this.Tree.TreeId, 
                EntityTokenSerializer.Serialize(parentEntityToken));                

            Element element = new Element(new ElementHandle(
                dynamicContext.ElementProviderName,
                entityToken,
                dynamicContext.Piggybag.PreparePiggybag(this.ParentNode, parentEntityToken)
                ));


            if (parentEntityToken is TreePerspectiveEntityToken)
            {
                element.ElementHandle.Piggyback[StringConstants.PiggybagTreeId] = Tree.TreeId;
            }

            var replaceContext = new DynamicValuesHelperReplaceContext(parentEntityToken, dynamicContext.Piggybag);

            element.VisualData = new ElementVisualizedData
            {
                Label = this.LabelDynamicValuesHelper.ReplaceValues(replaceContext),
                ToolTip = this.ToolTipDynamicValuesHelper.ReplaceValues(replaceContext),
                HasChildren = ChildNodes.Any(),
                Icon = this.Icon,
                OpenedIcon = this.OpenIcon
            };

            yield return element;
        }


        protected override void OnInitialize()
        {
            this.LabelDynamicValuesHelper = new DynamicValuesHelper(this.Label);
            this.LabelDynamicValuesHelper.Initialize(this);

            this.ToolTipDynamicValuesHelper = new DynamicValuesHelper(this.ToolTip);
            this.ToolTipDynamicValuesHelper.Initialize(this);
        }


        public override string ToString()
        {

            return string.Format("SimpleElementTreeNode, Id = {0}, Label = {1}", this.Id, this.Label);
        }
    }
}
